/* 输入：nums = [-1,0,1,2,-1,-4]
输出：[[-1,-1,2],[-1,0,1]]
解释：
nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。
nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。
nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。
不同的三元组是 [-1,0,1] 和 [-1,-1,2] 。 */

// 解法 1:三层循环
var threeSum = function (nums) {
    let res = [];
    nums.sort((a, b) => a - b);
    // console.log(nums); //[ -4, -1, -1, 0, 1, 2 ]
    for(let i = 0; i < nums.length; i++){
        if(i>0&& nums[i] === nums[i - 1]) continue;
        if(nums[i] > 0) break;
        for(let j = i + 1; j < nums.length; j++){
            if (j>i+1&& nums[j] === nums[j - 1]) continue;
            for (let k = j + 1; k < nums.length; k++) {
                if (k > j + 1&&nums[k] === nums[k - 1]) ; //跳过改次循环 去重
                if (nums[i] + nums[j] + nums[k] === 0) {
                    res.push([nums[i], nums[j], nums[k]]);
                }
            }
        }
    }
    return res
}
console.log(threeSum([-1, 0, 1, 2, -1, -4]));
// threeSum([-1, 0, 1, 2, -1, -4]);

//解法 2:排序 + 双指针
var threeSum = function(nums) {
  let res = [];
  nums.sort((a, b) => a - b);

  for (let i = 0; i < nums.length - 2; i++) {
    if (nums[i] > 0) break; // 由于排序，后面不可能为 0
    if (i > 0 && nums[i] === nums[i - 1]) continue; // 去重1️⃣

    let l = i + 1;
    let r = nums.length - 1;

    while (l < r) {
      const sum = nums[i] + nums[l] + nums[r];

      if (sum === 0) {
        res.push([nums[i], nums[l], nums[r]]);

        // 去重2️⃣ 跳过相同的 l、r 值
        while (l < r && nums[l] === nums[l + 1]) l++;
        while (l < r && nums[r] === nums[r - 1]) r--;

        l++;
        r--;
      } else if (sum < 0) {
        l++; // 和太小，左指针右移
      } else {
        r--; // 和太大，右指针左移
      }
    }
  }

  return res;
};

console.log(threeSum([-1, 0, 1, 2, -1, -4]));
// 输出: [ [ -1, -1, 2 ], [ -1, 0, 1 ] ]
